import axios from 'axios'
import store from '@/store'
import router from '../router'

const request = axios.create({
  baseURL: 'http://geek.itheima.net/v1_0/'
})

// ==================== 一.添加请求拦截器 ===========================
request.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么？=> 统一给header添加token
  /**
   * 需求：
   * 1. 已登录,有token
   * 2. 不是登录、注册等接口 (未登录/注册不能携带token)
   * 在请求头headers上 让authorizations携带token
   * 说明：authorizations 是登录的接口地址
   */
  if (store.state.user.token && config.url !== 'authorizations') {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// ==================== 二.添加响应拦截器 ===========================
request.interceptors.response.use(function (response) {
  // console.log('response返回: ', response)
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么
  const _data = {
    data: response.data.data,
    status: response.status,
    message: response.data.message
  }
  return _data
  // -------------------------- 错误响应 ------------------------------
}, async function (error) {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么
  // console.dir(error) // 错误提示

  // 说明：定义一个常量跳转回登录页面(可复用),  js中可以通过 router.currentRoute.path 获取当前访问页面的地址
  const loginPath = `/login?redirectUrl=${router.currentRoute.path}`
  try {
    // 处理401情况(response有错误,并且status=401)
    if (error.response && error.response.status === 401) {
      console.log('1.出现401情况!')
      /**
       * 思路：
       * 1. 没有登录, 没有token (从store获取token进行判断) ==> 跳回登录页
       *
       * 2. 已经登录（核心）=》有token=》{token:发请求, refresh_token：token失效，更新时使用}
       *    token过期了，refresh_token没有过期 =》使用refresh_token发请求，更新过期token=》重新发送上次401的请求
       * 3. token过期了，refresh_token过期了 ==> 跳转回登录页面（带上上次访问页面的地址）
       */

      // 第一种:
      // 没有登录 ==> 没有token (从store获取token)
      if (!store.state.user.token || !store.state.user.refresh_token) {
        // 跳转回登录页面
        router.replace(loginPath)
        // 中断请求，并抛出错误
        return Promise.reject(error)
      }

      // 第二种:
      // 已经登录（核心）==> 有token但失效了  {token:发请求, refresh_token：token失效，更新时使用}
      const { data } = await request({
        url: 'authorizations',
        method: 'PUT',
        headers: {
          Authorization:
            `Bearer ${store.state.user.refresh_token}`
        }
      })
      console.log('2.获取到的新token：', data)
      // data 是新获取的token
      store.commit('setToken',
        {
          token: data.token,
          refresh_token: store.state.user.refresh_token
        })
      // 重点：重新发送401的请求
      return request(error.config)
    }
  } catch (error) {
    // 第三种: token过期了，refresh_token过期了 ==> 跳转回登录页面（带上上次访问页面的地址）
    router.replace(loginPath)
    // 中断请求，并抛出错误
    return Promise.reject(error)
  }
  return Promise.reject(error)
})

export default request
